﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Xml.Linq;

namespace ROrganizer.Client
{
    internal static class ApplicationData
    {
        public static string Location { get; set; }

        internal const string HashRepository = "HashRepository.xml";
        internal const string ImdbRepository = "ImdbRepository.xml";
        internal const string MetaRepository = "MetaRepository.xml";
        internal const string Settings = "Settings.xml";

        public static XDocument GetDocument(string name)
        {
            ApplicationData.InitializeFile(name);
            return XDocument.Load(ApplicationData.GetPath(name));
        }

        public static void UpdateDocument(string name, XDocument document)
        {
            ApplicationData.InitializeFile(name);
            document.Save(ApplicationData.GetPath(name));
        }

        public static IDisposable OpenSession(string name)
        {
            return new DisposableMutext(name);
        }

        internal static void InitializeFile(string name)
        {
            var path = ApplicationData.GetPath(name);
            var folder = Path.GetDirectoryName(path);

            if (!Directory.Exists(folder))
                Directory.CreateDirectory(folder);

            if (!File.Exists(path))
                new XDocument(new XElement("ROrganizer")).Save(path);
        }

        private static string GetPath(string name)
        {
            var folder = ApplicationData.Location;

            if (String.IsNullOrEmpty(folder))
                folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

            folder = Path.Combine(folder, "adma");
            folder = Path.Combine(folder, "ROrganizer");
            folder = Path.Combine(folder, name);

            return folder;
        }

        private class DisposableMutext : IDisposable
        {
            private string name;
            private Mutex mutex;

            public DisposableMutext(string name)
            {
                this.name = name;             
                this.mutex = new Mutex(false, name);
                this.mutex.WaitOne();
            }

            public void Dispose()
            {
                this.mutex.ReleaseMutex();
                this.mutex.Close();
                this.mutex = null;
            }
        }
    }
}
